#include "cc9d.h"
#include "crc8.h"


namespace Chhol{
	static const byte SEPARATOR = 0x9d;//分隔符
	static const byte ESCAPE = 0x9e;//转义字符
	static const byte ESC_9D = 0xfe;//9D转义目标
	static const byte ESC_9E = 0xff;//9E转义目标

	void CC9D::sendByte(byte b){		
		byte e = (b + (ESC_9E - ESCAPE));
		if (e >= ESC_9D) {
			stream->write(ESCAPE);
			stream->write(e);
		} else {
			stream->write(b);
		}
	}
	void CC9D::send(sCc9dPkg * pkg_to_send){
		stream->write(SEPARATOR);			
		send_crc = 0xff;
		for(uint8 i =0;i<pkg_to_send->len;i++){
			byte b = pkg_to_send->datas[i];
			sendByte(b);
			crcInput(send_crc,b);
		}	
		sendByte(send_crc);	
		stream->write(SEPARATOR);	
	}
		

	uint8 CC9D::loop(){
		if(pkg_recving==0){
			return 0;
		}
		int b = stream->read();
		if(b == -1){
			return 0;
		}
		if (is_in_esc==true) {
			is_in_esc = false;
			if (b >= 0xfe) {
				recvData((byte)(b - ESC_9D + SEPARATOR));//b is fe => 9D ;b is ff => 9E
			} else {
				recvEsc(b);
			}
		} else {
			if (b == SEPARATOR) {
				recvEnd();
			} else if (b == ESCAPE) {
				is_in_esc = true;
			} else {
				recvData(b);
			}
		}
		return 1;
	}

	void CC9D::recvData(byte b) {
		crcInput(recv_crc,b);
		if (recv_ptr < max_len) {//如果收数据量不超过了缓冲区
			pkg_recving->datas[recv_ptr] = b;
			recv_ptr++;
		}
		else if (recv_ptr == max_len){//如果此处的数据已经超过缓冲区1Byte了，可能最后一个数是CRC
			recv_ptr++;
		}else{//如果此处的数据已经超过缓冲区多个Byte了，破坏CRC
			recv_crc=0xa4;
		}
	}
	void CC9D::recvEnd() {
		if (recv_crc == 0) {//crc 无误
			pkg_recving->len = recv_ptr-1;
			sCc9dPkg* next_pkg = receiced(pkg_recving);		
			if(next_pkg!= 0){
				pkg_recving = next_pkg;
			}		
		} 
		//继续收下一个包
		recv_ptr = 0;
		recv_crc = 0xff;
	}

	void CC9D::recvEsc(byte b) {
		
	}		
	void CC9D::init(sCc9dPkg* pkg_recv, uint8 max_buff_len){
		pkg_recving=pkg_recv;
		recv_ptr = 0;
		recv_crc = 0xff;
		max_len = max_buff_len;
		is_in_esc = false;
	}	
}

